package beautiful.butterfly.drds.datasource.connection_contexts.spi;

//import beautiful.butterfly.drds.datasource.author.Author;
//import beautiful.butterfly.drds.datasource.author.Authors;

import beautiful.butterfly.drds.datasource.connection_contexts.api.AbstractConnectionContextsFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Map;
import java.util.Properties;

/**
 * 属性配置
 */
// @Author(name = Authors.LI_YANG)
public class ConnectionContextsFactory extends AbstractConnectionContextsFactory {

    public static final Logger logger = LoggerFactory.getLogger(ConnectionContextsFactory.class);
    // base
    public final static String properties_url = "url";
    public final static String properties_default_catalog = "default_catalog";// 支持同数据库在竞争激烈的时候切换数据库
    public final static String properties_username = "username";
    public final static String properties_password = "password";

    //
    public final static String properties_default_readonly = "default_readonly";
    public final static String properties_default_auto_commit = "default_auto_commit";
    public final static String properties_default_transaction_isolation_level = "default_transaction_isolation_level";
    //

    public final static String properties_initial_size = "initial_size";
    public final static String properties_max_active = "max_active";
    public final static String properties_min_idle = "min_idle";
    public final static String properties_max_wait = "max_wait";
    //
    public final static String properties_test_on_borrow = "test_on_borrow";
    public final static String properties_test_on_return = "test_on_return";
    public final static String properties_test_while_idle = "test_while_idle";
    //
    public final static String properties_not_full_timeout_retry_count = "not_full_timeout_retry_count";

    public final static String properties_max_wait_not_empty_thread_count = "max_wait_not_empty_thread_count";

    public final static String properties_max_evictable_idle_timemillis = "max_evictable_idle_timemillis";

    public final static String properties_keep_alive = "keep_alive";

    public final static String properties_use_unfair_lock = "use_unfair_lock";

    public final static String properties_kill_when_socket_read_timeout = "kill_when_socket_read_timeout";
    public final static String properties_fail_fast = "fail_fast";
    public final static String properties_max_active_timeout_timemillis = "max_active_timeout_timemillis";

    public final static String properties_remove_abandoned_timeout_timemillis = "remove_abandoned_timeout_timemillis";

    //
    public final static String properties_time_between_eviction_runs_timemillis = "time_between_eviction_runs_timemillis";
    public final static String properties_min_evictable_idle_timemillis = "min_evictable_idle_timemillis";
    public final static String properties_max_alive_timeout_timemillis = "max_alive_timeout_timemillis";
    public final static String properties_validation_query_timeout_timemillis = "validation_query_timeout_timemillis";
    public final static String properties_access_to_underlying_connection_allowed = "access_to_underlying_connection_allowed";

    public final static String properties_connection_properties = "connection_properties";
    public final static String properties_init = "init";

    @SuppressWarnings("rawtypes")
    public ConnectionContexts createConnectionContexts(Properties properties) throws Exception {
        return createConnectionContexts((Map) properties);
    }

    @SuppressWarnings("rawtypes")
    public static ConnectionContexts createConnectionContexts(Map map) throws Exception {
        ConnectionContexts connectionContexts = new ConnectionContexts();
        config(connectionContexts, map);
        return connectionContexts;
    }

    @SuppressWarnings({"deprecation", "rawtypes"})
    public static void config(ConnectionContexts connectionContexts, Map<?, ?> map) throws SQLException {
        String value = null;
        value = (String) map.get(properties_url);
        if (value != null) {
            connectionContexts.setUrl(value);
        }
        value = (String) map.get(properties_default_catalog);
        if (value != null) {
            connectionContexts.setDefaultCatalog(value);
        }
        //
        value = (String) map.get(properties_username);
        if (value != null) {
            connectionContexts.setUsername(value);
        }
        value = (String) map.get(properties_password);
        if (value != null) {
            connectionContexts.setPassword(value);
        }
        //
        value = (String) map.get(properties_default_auto_commit);
        if (value != null) {
            connectionContexts.setDefaultAutoCommit(Boolean.valueOf(value).booleanValue());
        }

        value = (String) map.get(properties_default_readonly);
        if (value != null) {
            connectionContexts.setDefaultReadOnly(Boolean.valueOf(value).booleanValue());
        }
        value = (String) map.get(properties_default_transaction_isolation_level);
        if (value != null) {
            int defaultTransactionIsolationLevel = -1;
            if ("read_committed".equalsIgnoreCase(value)) {
                defaultTransactionIsolationLevel = Connection.TRANSACTION_READ_COMMITTED;
            } else if ("repeatable_read".equalsIgnoreCase(value)) {
                defaultTransactionIsolationLevel = Connection.TRANSACTION_REPEATABLE_READ;
            } else {
                throw new RuntimeException("else");
            }
            connectionContexts.setDefaultTransactionIsolationLevel(defaultTransactionIsolationLevel);
        } else {
            connectionContexts.setDefaultTransactionIsolationLevel(Connection.TRANSACTION_READ_COMMITTED);
        }

        //
        value = (String) map.get(properties_initial_size);
        if (value != null) {
            connectionContexts.setInitialSize(Integer.parseInt(value));
        }
        value = (String) map.get(properties_max_active);
        if (value != null) {
            connectionContexts.setMaxActive(Integer.parseInt(value));
        }
        value = (String) map.get(properties_min_idle);
        if (value != null) {
            connectionContexts.setMinIdle(Integer.parseInt(value));
        }
        value = (String) map.get(properties_max_wait);
        if (value != null) {
            connectionContexts.setMaxWaitTimeMillis(Long.parseLong(value));
        }

        // 随机测试
        value = (String) map.get(properties_test_on_borrow);
        if (value != null) {
            connectionContexts.setTestOnBorrow(Boolean.valueOf(value).booleanValue());
        }
        value = (String) map.get(properties_test_on_return);
        if (value != null) {
            connectionContexts.setTestOnReturn(Boolean.valueOf(value).booleanValue());
        }
        value = (String) map.get(properties_test_while_idle);
        if (value != null) {
            connectionContexts.setTestWhileIdle(Boolean.valueOf(value).booleanValue());
        }
        //
        value = (String) map.get(properties_validation_query_timeout_timemillis);
        if (value != null) {
            connectionContexts.setValidationQueryTimeout(Integer.parseInt(value));
        }
        value = (String) map.get(properties_remove_abandoned_timeout_timemillis);
        if (value != null) {
            connectionContexts.setRemoveAbandonedTimeout(Integer.parseInt(value));
        }
        value = (String) map.get(properties_max_alive_timeout_timemillis);
        if (value != null) {
            connectionContexts.setMaxAliveTimeOutTimeMillis(Long.parseLong(value));
        }
        //
        value = (String) map.get(properties_time_between_eviction_runs_timemillis);
        if (value != null) {
            connectionContexts.setTimeBetweenEvictionRunsMillis(Long.parseLong(value));
        }
        value = (String) map.get(properties_min_evictable_idle_timemillis);
        if (value != null) {
            connectionContexts.setMinEvictableIdleTimeMillis(Long.parseLong(value));
        }
        value = (String) map.get(properties_access_to_underlying_connection_allowed);
        if (value != null) {
            connectionContexts.setAccessToUnderlyingConnectionAllowed(Boolean.valueOf(value).booleanValue());
        }
        //
        value = (String) map.get(properties_connection_properties);
        if (value != null) {
            connectionContexts.setConnectionProperties(value);
        }
        value = (String) map.get(properties_init);
        if ("true".equals(value)) {
            connectionContexts.init();
        }
    }

}
